package com.uusee.crawler.framework;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.time.StopWatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.uusee.crawler.model.CrawlURI;

public abstract class AbstractJob implements Job {
	protected Log log = LogFactory.getLog("MtimeBaikeFastCrawlJob");
	protected ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 20, 0, TimeUnit.SECONDS,
			new ArrayBlockingQueue(5000), new ThreadPoolExecutor.CallerRunsPolicy());
	private boolean multiThreadFlag = true;
	private int startVid = 26000;
	private int endVid = 110000;
	
	private StopWatch stopWatch = new StopWatch();
	
	public AbstractJob() {
		stopWatch.start();
	}
	
	public void doExecute() {
		try {
			for (int i = startVid; i < endVid; i++) {
				try {
					if (multiThreadFlag) {
						assignTask(createCrawlURI(i+""),i);
					} else {
						crawl(createCrawlURI(i+""));
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (multiThreadFlag) {
				waitEnd();
			}
		} catch (Exception e) {
			log.error(e);
		}
	}
	
	protected void assignTask(CrawlURI crawlURI,int taskId) {
		try {
			CrawlThread crawlThread = new CrawlThread(crawlURI, this);
			threadPoolExecutor.execute(crawlThread);
			log.info("分配任务：" + taskId);
			
			long taskCount = threadPoolExecutor.getTaskCount();
			if (taskCount%100 == 0) {
				while(true) {
					try {
						Thread.sleep(10000);
					} catch (InterruptedException e) {
					}
					if (threadPoolExecutor.getActiveCount() == 0) {
						break;
					}
					log.info("完成任务数：" + threadPoolExecutor.getCompletedTaskCount()+",用时：" + stopWatch.getTime() / 1000 + "秒。");
				}
			}
		} catch(Exception e) {
			e.printStackTrace();
			log.error(e);
		}
	}
	
	protected void waitEnd() {
		log.info("任务分配完成，等待结束。");
		while (true) {
			log.info("完成任务数：" + threadPoolExecutor.getCompletedTaskCount());
			try {
				Thread.sleep(20000);
			} catch (InterruptedException e) {
			}
			if (threadPoolExecutor.getActiveCount() == 0) {
				stopWatch.stop();
				System.out.println("抓取结束,用时：" + stopWatch.getTime() / 1000 + "秒。");
				break;
			}
		}
	}

	public void setThreadPoolExecutor(ThreadPoolExecutor threadPoolExecutor) {
		this.threadPoolExecutor = threadPoolExecutor;
	}

	public void setMultiThreadFlag(boolean multiThreadFlag) {
		this.multiThreadFlag = multiThreadFlag;
	}

	public void setStartVid(int startVid) {
		this.startVid = startVid;
	}

	public void setEndVid(int endVid) {
		this.endVid = endVid;
	}
}
